package com.shop.cereshop.app.tencent.im.delay.handler;

import com.shop.cereshop.app.dao.tim.redpacket.RedPacketMapper;
import com.shop.cereshop.app.tencent.im.model.redpacket.RedPacket;
import com.shop.cereshop.app.tencent.im.delay.constant.TaskType;
import com.shop.cereshop.app.tencent.im.delay.model.DelayedTask;
import com.shop.cereshop.app.tencent.im.service.RedPacketService;
import com.shop.cereshop.commons.tencent.im.enums.redpacket.RedPacketStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @description:  红包过期自动取消任务处理器
 * @author zdd
 * @date 2025/9/24 10:27
 * @version 1.0
 */
@Component
@Slf4j
public class RedPacketTaskHandler implements DelayedTaskHandler {

    @Resource
    private RedPacketMapper redPacketMapper;
    @Resource
    private RedPacketService redPacketService;


    @Override
    public String getTaskType() {
        return TaskType.RED_PACKET;
    }

    @Override
    public boolean handle(DelayedTask task) {
        String packetId = task.getTaskId();
        // 幂等 + 状态检查，因为用户可能在“到期前1秒领取”，而消息已到期进入队列。消费时必须二次校验状态，避免误取消。
        if (isNoActionNeeded(packetId)) {
            log.info("红包 [{}] 已支付或不存在，跳过取消", packetId);
            return true;
        }

        // 执行过期未领取的红包退款
        log.info("开始执行过期未领取的红包退款: {}", packetId);
        boolean success = redPacketService.refund(packetId);
        if (success) {
            log.info("过期未领取的红包退款成功: {}", packetId);
            redPacketService.modifyTimMsg(packetId);
        } else {
            log.error("过期未领取的红包退款失败: {}", packetId);
        }
        return success;
    }

    /**
     * 判断红包是否不用处理退款
     *
     * @param packetId 红包ID
     * @return true: 不用处理，false: 需要处理
     */
    public boolean isNoActionNeeded(String packetId) {
        RedPacket redPacket = redPacketMapper.selectById(packetId);
        if (redPacket == null) {
            return true;
        }
        // 空值检查
        if (redPacket.getExpireTime() == null || redPacket.getStatus() == null) {
            return true;
        }
        // 判断是否已过期且未领取/未领完状态（过期时间 < 当前时间，且状态已经是未领取/未领完）
        boolean isExpiredAndNotReceived = redPacket.getExpireTime().isBefore(LocalDateTime.now())
                && (RedPacketStatusEnum.NOT_RECEIVED.getCode().equals(redPacket.getStatus())
                    || RedPacketStatusEnum.NOT_FINISHED.getCode().equals(redPacket.getStatus()));
        if (isExpiredAndNotReceived) {
            return false;
        }
        return true;
    }

}
